home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
graphsrc
/
config.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-05
|
6KB
|
197 lines
/*
config - read graphics device driver configuration file
Config reads command line-like switches from a configuration file.
Switches may have arguments, but not optional arguments. fname is
the name of the configuration file. cpath is NULL, or a string
containing a series of directories (optionally ending with '/' or
'\\'), separated by semicolons. pp points to an array of
structures, with one element per legal switch. The array is
terminated by an element starting with a zero. buf is a work array
of length bufsize.
In the configuration file, parameters are represented by switches like
those used on the command line. Switches introduced by '-' specify
final values of the corresponding parameters. Use '+' rather than
'-' if the given values are to be defaults only, and the driver is
to ask the user for the final values. Tokens (switches and parameters)
are separated by whitespace (spaces, tabs, or newlines). A semicolon
denotes a comment which extends to the end of the line.
If an illegal switch appears in the file, config prints an error
message to stderr and exits with an error.
The item pp[i]->ask points to an integer which is set to zero if the
switch was introduced by '-'. Note that, as in the example below,
more than one such item may point to the same integer. This can
be used if two switches are mutually exclusive, and using either
one should prevent a user query. Either pp[i]->ask or pp[i]->var
may be NULL. (There would be no point to setting both to NULL,
since config could then record no information about the switch.)
EXAMPLE...
Typical switches are...
-p ; portrait orientation
-l ; landscape orientation
-o <xoffset> <yoffset> ; offset from top left corner
-s <xsize> <ysize> ; plot size
-v <num> ; pen velocity
...which would be represented by this structure:
PARAM parmv[] = {{'o', REAL, &offset_ask, offsetv, 2},
{'s', REAL, &size_ask, sizev, 2},
{'v', REAL, &vel_ask, &vel, 1},
{'p', BOOLEAN, &orientation_ask, &portrait, 0},
{'l', BOOLEAN, &orientation_ask, &landscape, 0},
{'L', STRING, NULL, &plabel, 1},
{'\0'}};
The configuration file might contain:
-v 17 ; velocity
+o 0 1 ; offset (default only)
-p ; portrait orientation
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "config.h"
static FILE *cfile = stdin;
static char *gettok(char *buf, int bufsize)
{ static char separate[] = " \t\n";
char *s;
s = strtok(NULL, separate);
while(s == NULL)
{s = fgets(buf, bufsize, cfile);
if(s == NULL) return NULL;
s = strchr(buf, ';');
if(s != NULL) *s = 0; /* zap the comment */
s = strtok(buf, separate);
}
return s;
}
static cgripe(char *s, char *fname)
{ fprintf(stderr, "illegal parameter %s in configuration file %s\n",
s, fname);
exit(1);
}
config(char *fname, char *cpath, PARAM *pp, char *buf, int bufsize)
{ char c, *s;
int ask, found, i;
PARAM *np;
int *ip;
double *dp;
char *cp;
char **sp;
if(fname == NULL) return;
buf[0] = 0;
while(1)
{strncat(buf, fname, bufsize - strlen(fname) - 2);
cfile = fopen(buf, "r");
if(cfile != NULL) break; /* found configuration file */
if(cpath == NULL || *cpath == 0)
return; /* no configuration file */
for (i = 0; *cpath && *cpath != ';'; i++)
buf[i] = *cpath++;
if(*cpath) cpath++; /* step past the ';' */
if(i > 0)
{c = buf[i-1];
if(c != ':' && c != '\\' && c != '/')
buf[i++] = '/'; /* append '/' to path */
}
buf[i] = 0;
}
strtok("", " "); /* force initial read from file */
while((s = gettok(buf, bufsize)) != NULL)
{switch(s[0])
{case '-': ask = 0; break;
case '+': ask = 1; break;
default: cgripe(s, fname);
}
for (np = pp, found = 0; np->flag; np++)
{if(s[1] != np->flag) continue;
if(np->var == NULL) continue;
found = 1;
if(np->ask != NULL) *np->ask = ask;
if((np->type == BOOLEAN) && (np->nvar == 0))
{ip = (int *)np->var;
*ip = (int)(s[2] != '-');
}
ip = (int *)np->var;
dp = (double *)np->var;
cp = (char *)np->var;
sp = (char **)np->var;
for (i = 0; i < np->nvar ; i++)
{s = gettok(buf, bufsize);
if(s == NULL) return;
switch(np->type)
{case BOOLEAN: ip[i] = atoi(s); break;
case CHARACTER: cp[i] = s[0]; break;
case STRING: sp[i] = strdup(s); break;
case REAL: dp[i] = atof(s);
}
}
break;
}
if(!found) cgripe(s, fname);
}
}
#ifdef MAIN
int offset_doubt = 1;
int size_doubt = 1;
int vel_doubt = 1;
int orientation_doubt = 1;
int do_doubt = 1;
double offsetv[2] = {2.,1.}, sizev[2] = {6.,3.}, vel = 12.;
int portrait = 0, landscape = 0;
char *plabel = "default_string";
PARAM parmv[] = {{'o', REAL, &offset_doubt, offsetv, 2},
{'s', REAL, &size_doubt, sizev, 2},
{'v', REAL, &vel_doubt, &vel, 1},
{'p', BOOLEAN, &orientation_doubt, &portrait, 0},
{'l', BOOLEAN, &orientation_doubt, &landscape, 0},
{'L', STRING, NULL, &plabel, 1},
{'\0'}};
char buf[80];
main()
{ PARAM *pp;
int i;
printf("about to read file...\n");
config("TEST.CFG", ";d:\\bin/", parmv, buf, 80);
printf("file read\n");
for (pp = parmv; pp->flag; pp++)
{printf("%c: %10s\n", pp->flag, pp->ask[0]?"asking":"not asking");
for (i = 0; i < pp->nvar; i++)
switch(pp->type)
{case REAL: printf("\t\t%f\n", ((double *)pp->var)[i]); break;
case BOOLEAN: printf("\t\t%d\n", ((int *)pp->var)[i]); break;
case STRING: printf("\t\t%s\n", ((char **)pp->var)[i]); break;
case CHARACTER: printf("\t\t%c\n", ((char *)pp->var)[i]); break;
}
}
printf("structure printed\n");
printf("portrait = %d\n", portrait);
printf("landscape = %d\n", landscape);
}
#endif /* MAIN */